//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//

#include <windows.h>
#include <minshell.h>
#include <shellsdk.h>

void ShellNotifyCallback(
    DWORD cause, 
    DWORD proc, 
    DWORD thread
    )
{
    switch( cause )
    {
    case DLL_SYSTEM_STARTED:
        TaskBar_OnSystemStarted();
        break;
    case DLL_MEMORY_LOW:
        ::PostMessage( HWND_BROADCAST, WM_HIBERNATE, 0, 0 );
        break;
    case DLL_PROCESS_DETACH:
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_EXITING:
    default:
        break;
    }
}

void ShellApiReservedForNK( 
    void
    )
{
    ASSERT( 0 ); // This should never be called.
}

DWORD SHUnsupportedFunc( 
    void 
    )
{
    RETAILMSG( 1, ( L"WARNING: SHUnsupportedFunc called!\r\n" ) );
    SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
    return 0;
}

BOOL ShellExecuteExUnsupportedFunc( 
    LPSHELLEXECUTEINFO lpExecInfo,
    DWORD cbExecInfo
    )
{
    if( cbExecInfo != sizeof( SHELLEXECUTEINFO ) )
        return FALSE;

    if( _tcscmp( lpExecInfo->lpFile, TEXT( ":MSREMNET" ) ) )
    {
        RETAILMSG( 1, ( TEXT( "  *****    \r\n" ) ) );
        RETAILMSG( 1, ( TEXT( "  ***** %s \r\n" ), lpExecInfo->lpParameters ) );
        RETAILMSG( 1, ( TEXT( "  *****    \r\n" ) ) );

        ASSERT( 0 );
        return TRUE;
    }
    return SHUnsupportedFunc();
}

const PFNVOID VTable[] = 
{
    (PFNVOID) ShellNotifyCallback,
    (PFNVOID) ShellApiReservedForNK,                // Reserved for NK
    (PFNVOID) ShellExecuteExUnsupportedFunc,        
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//5
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//10
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//15
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//20
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//25
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//30
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//35
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//40
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//45
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//50
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//55
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//60
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//65
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
//70
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,
    (PFNVOID) SHUnsupportedFunc,

// ----- All of our API would go below here -----
//75
    (PFNVOID) SHUnsupportedFunc,                    // _xxx_SHMenuAddItem
    (PFNVOID) SHUnsupportedFunc,                    // _xxx_SHMenuSetAttribute,
    (PFNVOID) SHUnsupportedFunc,                    // _xxx_SHMenuRemoveItem,
    (PFNVOID) SHUnsupportedFunc,                    // _xxx_SHMenuRemoveAllItems,
    (PFNVOID) SHUnsupportedFunc,                    // _xxx_SHMenuShow,
//80                                                   
    (PFNVOID) SHUnsupportedFunc,                    // _xxx_SHMenuIsItemExist,
    (PFNVOID) SHUnsupportedFunc,                    // _xxx_SHMenuUpdateItem,
    (PFNVOID) SHUnsupportedFunc,                    // _xxx_SHMenuSetItemVoiceCommand,
    (PFNVOID) SHUnsupportedFunc,                    // _xxx_SHMenuSetCurrentItem,
    (PFNVOID) SHUnsupportedFunc,                    
//85                                                   
    (PFNVOID) SHUnsupportedFunc,                    // _xxx_SHRegisterDisplayIdleNotification,
    (PFNVOID) SHUnsupportedFunc,                    // _xxx_SHUnregisterDisplayIdleNotification,
    (PFNVOID) SHUnsupportedFunc,                    // _xxx_SHRegisterIdleKey,   
    (PFNVOID) SHUnsupportedFunc,                    // _xxx_SHUnregisterIdleKey,   
    (PFNVOID) SHUnsupportedFunc,                       
};

const ULONGLONG SigTable[] = {
    FNSIG3( DW, DW, DW ),                           // ShellNotifyCallback
    FNSIG0(),                                       
    FNSIG2( I_PTR, DW ),                            // ShellExecuteExUnsupported
    FNSIG0(),
    FNSIG0(), 
//5
    FNSIG0(), 
    FNSIG0(), 
    FNSIG0(), 
    FNSIG0(), 
    FNSIG0(), 
//10
    FNSIG0(), 
    FNSIG0(), 
    FNSIG0(), 
    FNSIG0(), 
    FNSIG0(), 
//15
    FNSIG0(), 
    FNSIG0(), 
    FNSIG0(), 
    FNSIG0(), 
    FNSIG0(), 
//20
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
//25
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
//30
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
//35
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
//40
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
//45
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
//50
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
//55
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
//60
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
//65
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
//70
    FNSIG0(),
    FNSIG0(),
    FNSIG0(), 
    FNSIG0(), 
    FNSIG0(), 

// ----- All of our API is below here -----
//75
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
//80
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(),
    FNSIG0(), 
//85
    FNSIG0(),
    FNSIG0(),
    FNSIG0(), 
    FNSIG0(), 
    FNSIG0(), 
};

HANDLE RegisterShellAPI(
    void
    )
{
    HANDLE hShellAPI = CreateAPISet(
        "SHEL", 
        sizeof( SigTable ) / sizeof( SigTable[0] ), 
        VTable, 
        SigTable 
    );

    if( hShellAPI && !RegisterAPISet(hShellAPI, SH_SHELL) )
    {
        CloseHandle( hShellAPI );
        hShellAPI = NULL;
    }
    return hShellAPI;
}

